package com.xvdong.gadget.appium;

import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;

import java.time.Duration;

import io.appium.java_client.AppiumBy;
import io.appium.java_client.TouchAction;
import io.appium.java_client.android.AndroidDriver;
import io.appium.java_client.android.nativekey.AndroidKey;
import io.appium.java_client.android.nativekey.KeyEvent;
import io.appium.java_client.touch.WaitOptions;
import io.appium.java_client.touch.offset.PointOption;

/**
 * Created by xvDong on 2025/6/19.
 */

public class BaseApp {

    protected String AppPackageName = "";
    protected AndroidDriver mDriver;

    //用户相关的测试
    protected void userTest(String resId) {
        try {
            waitClickElementById(resId);
            waitClickElementById("btn_add");
            Thread.sleep(3000);
            //返回键先退出键盘
            if (mDriver == null){
                System.out.println("设备为空,请重新初始化设备!");
                throw new RuntimeException("设备为空,请重新初始化设备!");
            }
            mDriver.pressKey(new KeyEvent(AndroidKey.BACK));
            inputElement("et_name", "万寿帝君");
            inputElement("et_age", "99");
            inputElement("et_phone", "13788888888");
            inputElement("et_eye_distance", "65");
            inputElement("et_address", "大高玄殿\r\n->景山前街以北，景山西街以东，陟山门街以南。 此处地处北京皇城之内，北海公园以东，景山公园以西。");
            inputElement("et_remark", "此人乃嘉靖也");
            waitClickElementById("btn_save");

            Thread.sleep(3000);
            clickRecyclerItemButton(AppPackageName + ":id/recyclerview", 1, AppPackageName + ":id/btn_edit");
            Thread.sleep(3000);
            mDriver.pressKey(new KeyEvent(AndroidKey.BACK));
            inputElement("et_name", "万寿帝君(改)");
            waitClickElementById("btn_save");
            Thread.sleep(3000);

            //删除用户
//            clickRecyclerItemButton(AppPackageName + ":id/recyclerview", 1, AppPackageName + ":id/btn_add");
//            waitClickElementById("iv_confirm");

            //返回首页
            waitClickElementById("btn_back");

        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
    }

    //门店信息的相关测试
    protected void shopTest(String resId) {
        try {
            waitClickElementById(resId);
            Thread.sleep(3000);

            //返回键先退出键盘
            inputElement("et_shop_name", "旭东1号店");
            inputElement("et_contact_person", "妙一飞玄真君");
            inputElement("et_contact_type", "13888888888");
            inputElement("et_shop_address", "吉林省长春市武汉路1888号");
            inputElement("et_remark", "暂无");

            clickElementById("iv_save");

            Thread.sleep(3000);

        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
    }

    //选项的相关测试
    protected void settingsTest(String resId) {
        waitClickElementById(resId);
        //时间设置
        waitClickElementById("iv_settings_correction");
        waitClickElementById("iv_back");
        //打印设置
        waitClickElementById("iv_settings_print");
        waitClickElementById("iv_back");
        //音量设置
        waitClickElementById("iv_settings_volume");
        waitClickElementById("iv_back");
        //WiFi设置
        waitClickElementById("iv_settings_wifi");
        waitClickElementById("iv_back");
        //清除缓存
        waitClickElementById("iv_setting_catch");
        waitClickElementById("iv_confirm");
        try {
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
        //软件升级
        waitClickElementById("iv_setting_update");
        waitClickElementById("iv_back");
        //数据库备份/恢复
        waitClickElementById("iv_setting_other");
        waitClickElementById("iv_back");
        //关于版本
        waitClickElementById("iv_setting_version");
        waitClickElementById("iv_back");
        //返回主页
        waitClickElementById("iv_back");
    }

    //自动训练  从首页出发
    protected void trainTest(String resId) {
        try {
            waitClickElementById(resId);
            String[] category = {"正镜阅读", "负镜阅读", "调节灵敏度", "集合训练", "散开训练", "垂直融像", "跳跃融像", "随机融像"
                    , "聚散灵敏度", "同时视训练", "自定义融像", "立体视训练", "视觉刺激①", "视觉刺激②", "视觉刺激③", "扫视训练", "追随训练"
                    , "眼球运动", "扇形视标", "精细目力"};

//            String[] category = {"Convering lens", "Divering lens", "Flipper", "Bifixation", "Convergence", "Divergence",
//                    "FVF", "Stereography", "Jump fusion", "Random fusion", "Custom fusion", "Vertical fusion",
//                    "Amblyopia①", "Amblyopia②", "Amblyopia③", "Epicritic vision", "Flicks", "Eye tracking", "Eye movements", "Acuity"};

            /*选择训练项页面*/
            Thread.sleep(3000);
            for (String item : category) {
                waitClickElementByText(item);
            }

            waitClickElementById("iv_start");

            Thread.sleep(3000);

            /*配置训练页面*/
            WebElement saveTrain = mDriver.findElement(AppiumBy.id(AppPackageName + ":id/iv_save"));
            for (int i = 0; i < category.length; i++) {
                saveTrain.click();
                Thread.sleep(1500);
            }
            Thread.sleep(3000);

            /*我的方案页面*/
            mDriver.findElement(AppiumBy.id(AppPackageName + ":id/iv_save")).click();
            Thread.sleep(3000);
            KeyEvent keyEnter = new KeyEvent(AndroidKey.ENTER);
            KeyEvent keyUp = new KeyEvent(AndroidKey.DPAD_UP);
            for (int i = 0; i < category.length; i++) {
                /*训练列表页面*/
                waitClickElementById("iv_start");
                System.out.println("第" + i + "项目训练开始");
                Thread.sleep(3000);
                /*正镜阅读训练*/
                mDriver.pressKey(keyEnter);   // 回车键
                int time = 180;
                if (i == 3) {
                    time = 300;
                }
                for (int j = 0; j < time; j++) {
                    Thread.sleep(1000);
                    mDriver.pressKey(keyUp);   // 回车键
                    System.out.println("运行第" + j + "秒时间了");
                }
                System.out.println("这项训练完成了!!");
            }
            Thread.sleep(30000);
            //返回首页
            mDriver.findElement(AppiumBy.id(AppPackageName + ":id/iv_back_home")).click();
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            System.out.println("InterruptedException");
        }
    }

    protected void detectionTest(String resId) {
        try {
            Thread.sleep(7000);
            waitClickElementById(resId);
            String[] category = {"Worth-4dots", "立体视", "垂直眼位", "水平眼位", "AC/A", "NRA", "BCC", "PRA"
                    , "AMP", "Flipper", "单眼正镜\n接受能力", "单眼负镜\n接受能力", "聚散灵敏度", "散开范围", "集合范围", "不等像"};
            waitClickElementById("iv_all_select");//全选
            waitClickElementByText("立体视");//取消立体视
            waitClickElementById("iv_detection_start");//开始
            waitClickElementById("tv_visual1");//选择<20/50
            waitClickElementById("iv_detection_next");//下一步
            KeyEvent keyEnter = new KeyEvent(AndroidKey.ENTER);
            KeyEvent keyUp = new KeyEvent(AndroidKey.DPAD_UP);

            //Worth-4dots
            Worth_4dots(keyEnter);
            //立体视
//            立体视(keyEnter, keyUp);
            //垂直眼位
            垂直眼位(keyEnter);
            //水平眼位
            水平眼位(keyEnter);
            //AC/A
            AC_A(keyEnter, keyUp);
            //NRA
            NRA(keyEnter);
            //BCC
            BCC(keyEnter);
            //PRA
            PRA(keyEnter);
            //AMP
            AMP(keyEnter);
            //Flipper
            Flipper(keyEnter, keyUp);
            //单眼正镜
            单眼正镜(keyEnter);
            //单眼负镜
            单眼负镜(keyEnter);
            //聚散灵敏度
            聚散灵敏度(keyEnter, keyUp);
            //散开
            散开(keyEnter, keyUp);
            //集合
            集合(keyEnter, keyUp);
            //不等像
            不等像(keyEnter);
            //等结果
            Thread.sleep(30000);

            waitClickElementById("iv_back");
            waitClickElementById("iv_confirm");

        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
    }

    private void 不等像(KeyEvent keyEnter) throws InterruptedException {
        Thread.sleep(3000);
        mDriver.pressKey(keyEnter);
        System.out.println("不等像");
        Thread.sleep(3000);
        mDriver.pressKey(keyEnter);
        Thread.sleep(6000);
    }

    private void 集合(KeyEvent keyEnter, KeyEvent keyUp) throws InterruptedException {
        Thread.sleep(3000);
        mDriver.pressKey(keyEnter);
        System.out.println("集合");
        Thread.sleep(3000);
        mDriver.pressKey(keyUp);
        waitClickElementById("iv_end");
        Thread.sleep(6000);
    }

    private void 散开(KeyEvent keyEnter, KeyEvent keyUp) throws InterruptedException {
        Thread.sleep(3000);
        mDriver.pressKey(keyEnter);
        System.out.println("散开");
        Thread.sleep(3000);
        mDriver.pressKey(keyUp);
        waitClickElementById("iv_end");
        Thread.sleep(6000);
    }

    private void 聚散灵敏度(KeyEvent keyEnter, KeyEvent keyUp) throws InterruptedException {
        Thread.sleep(3000);
        mDriver.pressKey(keyEnter);
        System.out.println("聚散灵敏度");
        Thread.sleep(3000);
        for (int i = 0; i < 60; i++) {
            mDriver.pressKey(keyUp);
            System.out.println("运行第" + i + "秒时间了");
            Thread.sleep(1000);
        }
        Thread.sleep(3000);
    }

    private void 单眼负镜(KeyEvent keyEnter) throws InterruptedException {
        Thread.sleep(3000);
        mDriver.pressKey(keyEnter);
        System.out.println("单眼负镜");
        Thread.sleep(5000);
        waitClickElementById("iv_confirm");
        for (int i = 0; i < 7; i++) {
            waitClickElementById("iv_clear");
            System.out.println("运行第" + i + "秒时间了");
            Thread.sleep(4000);
        }
        waitClickElementById("iv_confirm");
        Thread.sleep(4000);
        for (int i = 0; i < 7; i++) {
            waitClickElementById("iv_clear");
            System.out.println("运行第" + i + "秒时间了");
            Thread.sleep(4000);
        }
        Thread.sleep(4000);
    }

    private void 单眼正镜(KeyEvent keyEnter) throws InterruptedException {
        Thread.sleep(3000);
        mDriver.pressKey(keyEnter);
        System.out.println("单眼正镜");
        Thread.sleep(5000);
        waitClickElementById("iv_confirm");
        Thread.sleep(3000);
        for (int i = 0; i < 3; i++) {
            waitClickElementById("iv_clear");
            System.out.println("运行第" + i + "秒时间了");
            Thread.sleep(4000);
        }
        waitClickElementById("iv_confirm");
        Thread.sleep(4000);
        for (int i = 0; i < 3; i++) {
            waitClickElementById("iv_clear");
            System.out.println("运行第" + i + "秒时间了");
            Thread.sleep(4000);
        }
        Thread.sleep(4000);
    }

    private void Flipper(KeyEvent keyEnter, KeyEvent keyUp) throws InterruptedException {
        Thread.sleep(3000);
        mDriver.pressKey(keyEnter);
        System.out.println("Flipper");
        Thread.sleep(3000);
        waitClickElementById("iv_confirm");
        Thread.sleep(3000);
        for (int i = 0; i < 60; i++) {
            mDriver.pressKey(keyUp);
            System.out.println("双眼运行第" + i + "秒时间了");
            Thread.sleep(1000);
        }
        Thread.sleep(3000);
        waitClickElementById("iv_confirm");
        for (int i = 0; i < 60; i++) {
            mDriver.pressKey(keyUp);
            System.out.println("右眼运行第" + i + "秒时间了");
            Thread.sleep(1000);
        }
        Thread.sleep(3000);
        waitClickElementById("iv_confirm");
        for (int i = 0; i < 60; i++) {
            mDriver.pressKey(keyUp);
            System.out.println("左眼运行第" + i + "秒时间了");
            Thread.sleep(1000);
        }
        Thread.sleep(7000);
    }

    private void AMP(KeyEvent keyEnter) throws InterruptedException {
        Thread.sleep(3000);
        mDriver.pressKey(keyEnter);
        System.out.println("AMP");
        Thread.sleep(5000);
        waitClickElementById("iv_confirm");
        Thread.sleep(6000);
        for (int i = 0; i < 7; i++) {
            waitClickElementById("iv_clear");
            System.out.println("运行第" + i + "秒时间了");
            Thread.sleep(4000);
        }
        waitClickElementById("iv_confirm");
        Thread.sleep(3000);
        for (int i = 0; i < 7; i++) {
            waitClickElementById("iv_clear");
            System.out.println("运行第" + i + "秒时间了");
            Thread.sleep(4000);
        }
        Thread.sleep(3000);
    }

    private void PRA(KeyEvent keyEnter) throws InterruptedException {
        Thread.sleep(3000);
        mDriver.pressKey(keyEnter);
        System.out.println("PRA");
        Thread.sleep(3000);
        for (int i = 0; i < 7; i++) {
            waitClickElementById("iv_clear");
            System.out.println("运行第" + i + "秒时间了");
            Thread.sleep(4000);
        }
        Thread.sleep(6000);
    }

    private void BCC(KeyEvent keyEnter) throws InterruptedException {
        Thread.sleep(3000);
        mDriver.pressKey(keyEnter);   // 回车键
        System.out.println("BCC");
        Thread.sleep(3000);
        waitClickElementById("iv_bt_sure");
        Thread.sleep(7000);
    }

    private void NRA(KeyEvent keyEnter) throws InterruptedException {
        Thread.sleep(3000);
        mDriver.pressKey(keyEnter);   // 回车键
        System.out.println("NRA");
        Thread.sleep(3000);
        for (int i = 0; i < 3; i++) {
            waitClickElementById("iv_clear");
            System.out.println("运行第" + i + "秒时间了");
            Thread.sleep(4000);
        }
        Thread.sleep(6000);
    }

    private void AC_A(KeyEvent keyEnter, KeyEvent keyUp) throws InterruptedException {
        Thread.sleep(3000);
        mDriver.pressKey(keyEnter);   // 回车键
        System.out.println("AC/A");
        Thread.sleep(3000);
        mDriver.pressKey(keyEnter);   // 回车键
        Thread.sleep(3000);
        mDriver.pressKey(keyUp);
        Thread.sleep(3000);
        mDriver.pressKey(keyEnter);   // 回车键
        Thread.sleep(6000);
    }

    private void 水平眼位(KeyEvent keyEnter) throws InterruptedException {
        Thread.sleep(3000);
        mDriver.pressKey(keyEnter);
        System.out.println("水平眼位");
        Thread.sleep(3000);
        mDriver.pressKey(keyEnter);   // 回车键
        Thread.sleep(6000);
    }

    private void 垂直眼位(KeyEvent keyEnter) throws InterruptedException {
        Thread.sleep(3000);
        mDriver.pressKey(keyEnter);
        System.out.println("垂直眼位");
        Thread.sleep(3000);
        mDriver.pressKey(keyEnter);   // 回车键
        Thread.sleep(6000);
    }

    private void 立体视(KeyEvent keyEnter, KeyEvent keyUp) throws InterruptedException {
        Thread.sleep(3000);
        mDriver.pressKey(keyEnter);
        System.out.println("立体视");
        Thread.sleep(3000);
        mDriver.pressKey(keyUp);
        waitClickElementById("iv_end");
        Thread.sleep(6000);
    }

    private void Worth_4dots(KeyEvent keyEnter) throws InterruptedException {
        Thread.sleep(2000);
        mDriver.pressKey(keyEnter);   // 回车键
        System.out.println("Worth-4dots");
        Thread.sleep(3000);
        waitClickElementById("iv_sync_confirm");
        Thread.sleep(2000);
        waitClickElementById("iv_sync_confirm");
        Thread.sleep(6000);
    }

    //延迟1秒点击
    private void clickElementById(String id) {
        try {
            mDriver.findElement(AppiumBy.id(AppPackageName + ":id/" + id)).click();
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
    }

    //EditText的输入
    private void inputElement(String id, String value) {
        try {
            WebElement editInput = mDriver.findElement(AppiumBy.id(AppPackageName + ":id/" + id));
            editInput.clear();                      //清空已有内容
            editInput.sendKeys(value);      //英文输入
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            System.out.println(e.getMessage());
        }
    }


    //等待View出现后点击,替换Thread.sleep()
    private void waitClickElementById(String id) {
        try {
            WebDriverWait wait = new WebDriverWait(mDriver, Duration.ofSeconds(10)); // 最多等10秒
            wait.until(ExpectedConditions.elementToBeClickable(AppiumBy.id(AppPackageName + ":id/" + id))).click();
        } catch (Exception e) {
            System.out.println("---------" + e.getMessage() + "-----------");
        }
    }

    /*根据文字等待View出现后点击,替换Thread.sleep()*/
    private void waitClickElementByText(String Text) {
        WebDriverWait wait = new WebDriverWait(mDriver, Duration.ofSeconds(10)); // 最多等10秒
        wait.until(ExpectedConditions.elementToBeClickable(AppiumBy.xpath(".//*[@text='" + Text + "']"))).click();
    }

    //点击列表中的item
    private void waitClickList(String itemId, int index, String text) {
        // 添加显式等待的示例
        WebDriverWait wait = new WebDriverWait(mDriver, Duration.ofSeconds(10));
        WebElement deleteButton = wait.until(ExpectedConditions.elementToBeClickable(
                By.xpath("(//*[@resource-id='" + itemId + "'])[" + index + "]//*[@resource-id='" + text + "']")
        ));
        deleteButton.click();
    }

    //点击列表中的item
    private void clickRecyclerItemButton(String recyclerId, int itemIndex, String targetBtnId) {
        WebDriverWait wait = new WebDriverWait(mDriver, Duration.ofSeconds(10));
        // 滚动到某个大概按钮，确保 item 被加载出来（提高成功率）
        String scrollScript =
                "new UiScrollable(new UiSelector().resourceId(\"" + recyclerId + "\"))" +
                        ".scrollIntoView(new UiSelector().resourceId(\"" + targetBtnId + "\"))";
        mDriver.findElement(AppiumBy.androidUIAutomator(scrollScript));

        // 构造 XPath：RecyclerView 中第 N 个 item（RelativeLayout）
        String itemXpath = String.format(
                "//androidx.recyclerview.widget.RecyclerView[@resource-id='%s']/*[%d]",
                recyclerId, itemIndex + 1 // XPath index 从 1 开始
        );

        WebElement itemElement = wait.until(ExpectedConditions.presenceOfElementLocated(By.xpath(itemXpath)));

        // 在这个 item 中查找编辑按钮
        WebElement editBtn = itemElement.findElement(By.id(targetBtnId));

        // 点击按钮
        wait.until(ExpectedConditions.elementToBeClickable(editBtn)).click();
    }



    //API接口的测试
    protected void apiTest() {
        try {
            waitClickElementById("imageview4");
            Thread.sleep(3000);

            waitClickElementById("iv_setting_version");
            Thread.sleep(3000);

            WebElement btnLogin = mDriver.findElement(AppiumBy.id(AppPackageName + ":id/tv_softwarename"));
            btnLogin.click();
            Thread.sleep(100);
            btnLogin.click();
            Thread.sleep(100);
            btnLogin.click();
            Thread.sleep(100);
            btnLogin.click();
            Thread.sleep(100);
            btnLogin.click();
            Thread.sleep(3000);

            waitClickElementById("iv_api");
            Thread.sleep(3000);

            mDriver.pressKey(new KeyEvent(AndroidKey.BACK));
            inputElement("et_up_shop", "http://192.168.101.186:8080/v1/add/shop/info");
            inputElement("et_up_user", "http://192.168.101.186:8080/v1/user/add/list");
            inputElement("et_up_train_plan", "http://192.168.101.186:8080/v1/train/plan/add/list");
            inputElement("et_up_train_report", "http://192.168.101.186:8080/v1/train/result/add/list");

//            inputElement("et_down_shop", "http://192.168.101.186:8080/v1/get/shop/info");
//            inputElement("et_down_user", "http://192.168.101.186:8080/v1/get/user/list");
//            inputElement("et_down_train_plan", "http://192.168.101.186:8080/v1/get/train/plan/list");
//            inputElement("et_down_train_report", "http://192.168.101.186:8080/v1/get/train/result/list");

            waitClickElementById("iv_save");
            Thread.sleep(3000);
            clickElementById("iv_confirm");
            Thread.sleep(3000);

//            driver.pressKey(new KeyEvent(AndroidKey.BACK));
//            Thread.sleep(3000);
//            driver.pressKey(new KeyEvent(AndroidKey.BACK));
//            Thread.sleep(3000);
//            driver.pressKey(new KeyEvent(AndroidKey.BACK));
//            Thread.sleep(3000);

        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
    }

    //获取元素
    private void findElement(WebElement el) {
        // ID定位（推荐首选）
        WebElement btnLogin = mDriver.findElement(AppiumBy.id(AppPackageName + ":id/login_btn"));
        btnLogin.click();

        // Class定位（适用于原生组件）
        WebElement firstBtn = mDriver.findElements(AppiumBy.className(".android.widget.Button")).get(0);
        firstBtn.click();

        // XPath定位（复杂场景）
        WebElement saveBtn = mDriver.findElement(AppiumBy.xpath(".//*[@text='保存']"));
        saveBtn.click();

        // UIAutomato定位（动态内容）
        WebElement dynamicEl = mDriver.findElement(AppiumBy.androidUIAutomator(".new UiSelector().description(\"菜单\")"));
        el.click();
    }


    //手势操作（拖拽、滑动）
    public void swipeGesture(AndroidDriver driver) {
        TouchAction action = new TouchAction(driver);
        action.press(PointOption.point(500, 1200))
                .waitAction(WaitOptions.waitOptions(Duration.ofMillis(500)))
                .moveTo(PointOption.point(500, 300))
                .release()
                .perform();
    }
}
